#pragma once
#include"../LibDGGSBase/MathDefine.hpp"
#include"../LibDGGSKernel/IDGGSKernel.hpp"
#include"../LibGridTIFF/GridTIFF.hpp"
#include"../3rdlibs/include/json/json.h"
#include <filesystem>
#include <ostream>
#include <fstream>
#include <iostream>
_NNU_DGGS_BEGIN
using namespace Base;
using namespace Kernel;
namespace Field {

    template<typename T>
    class DGGSFieldBand;

    /// <summary>
    /// 格网数据的field的Layer结构定义
    /// </summary>
    template<typename T>
    class DGGSFieldLayer
    {
    private:
        DGGSDataType        _dataType = DGGSDataType::DGGS_Unknown;         //数据类型
        DGGSGridType        _gridType = DGGSGridType::Unknown;              //格网类型
        DGGSElementType     _elementType = DGGSElementType::Unknown;        //格网要素类型
        int                 _bandCount = 0;                                 //波段数
        int                 _level = 1;                                     //水平层级
        DGGSFieldBand<T>*   _bands = nullptr;                               //波段数据
        double*             _bound= nullptr;

        /// <summary>
        /// 计算分辨率
        /// </summary>
        double calculateDiffer(int level);

        /// <summary>
        /// 获取包围盒
        /// </summary>
        void getBoxFromBound(const double* bound, DGGridBBox*& tempGridBBoxes, int gridBoxCount);

#pragma region 读写辅助函数

        /// <summary>
        /// 获取GridTIFF2D的GridTransform
        /// </summary>
        /// <param name="gridBBox">格网包围盒</param>
        /// <param name="level">层级</param>
        GridTransform getGridTransFromGridBox(DGGridBBox gridBBox);

        /// <summary>
        /// 获取GridTIFF2D的BandValue
        /// </summary>
        /// <param name="fieldBand">FieldBand</param>
        /// <param name="gridBBox">格网包围盒</param>
        /// <param name="GridTIFFValues">GridTIFF2D的BandValue</param>
        bool getPartitionValues(int bandId, DGGridBBox gridBBox,T*&GridTIFFValues);

        /// <summary>
        /// 获取格网包围盒
        /// </summary>
        /// <param name="gridTrans">格网变换</param>
        /// <param name="gridSize">格网大小</param>
        /// <returns></returns>
        DGGridBBox getGridBoxFromGridTrans(GridTransform gridTrans,int gridSize);

        /// <summary>
        /// 从Json文件加载FieldLayer参数数据
        /// </summary>
        /// <param name="fieldLayer">FieldLayer</param>
        /// <param name="fieldJsonFile">json文件名</param>
        void loadFromJson(const char* fieldJsonFile);

        /// <summary>
        /// 设置GridTIFF2D的BandValue
        /// </summary>
        /// <param name="fieldBand">FieldBand</param>
        /// <param name="gridBBox">格网包围盒</param>
        /// <param name="GridTIFFValues">GridTIFF2D的BandValue</param>
        bool setBandValues(int bandId, DGGridBBox gridBBox, T *GridTIFFValues);

        /// <summary>
        /// 判断文件是否为TIFF文件
        /// </summary>
        /// <param name="fileName">文件名</param>
        bool isTiffFile(const char* fileName);

        /// <summary>
        /// 仅从GridTIFF文件加载FieldLayer参数及属性数据
        /// </summary>
        /// <param name="fieldLayer">FieldLayer</param>
        /// <param name="fieldFilePath">文件路径</param>
        /// <returns></returns>
        bool loadFromGridTiff(const char* fieldFileName);
# pragma endregion

    public:
        DGGSFieldLayer();

        DGGSFieldLayer(int bandCount, DGGSDataType dataType, DGGSElementType elementType, DGGSGridType gridType, int level, double* bound = nullptr);

        ~DGGSFieldLayer();

        /// <summary>
        /// 获取格网类型
        /// </summary>
        DGGSGridType getGridType() { return this->_gridType; }

        /// <summary>
        /// 设置格网类型
        /// </summary>
        void setGridType(DGGSGridType gridType) { this->_gridType = gridType; }

        /// <summary>
        /// 获取格网单元类型
        /// </summary>
        DGGSElementType getElementType() { return this->_elementType; }

        /// <summary>
        /// 设置格网单元类型
        /// </summary>
        void setElementType(DGGSElementType elementType) { this->_elementType = elementType; }

        /// <summary>
        /// 设置波段数量
        /// </summary>
        /// <param name="bandCount">波段数</param>
        void setBandCount(int bandCount);

        /// <summary>
        /// 设置层级
        /// </summary>
        /// <param name="level">层级</param>
        void setLevel(int level) { this->_level = level; }

        /// <summary>
        /// 获取层级
        /// </summary>
        /// <returns>int level</returns>
        int getLevel() { return this->_level; }

        /// <summary>
        /// 获取波段数量
        /// </summary>
        /// <returns>int Count</returns>
        int getbandCount() { return this->_bandCount; }

        /// <summary>
        /// 获取数据类型
        /// </summary>
        /// <returns>DGGSDataType dataType</returns>
        DGGSDataType getDataType() { return this->_dataType; }

        /// <summary>
        /// 设置数据类型
        /// </summary>
        void setDataType(DGGSDataType dataType) { this->_dataType = dataType; }

        /// <summary>
        /// 根据索引获取波段
        /// </summary>
        /// <returns>DGGSFieldBand </returns>
        DGGSFieldBand<T>* getBand(int bandId);

        /// <summary>
        /// 获取包围盒
        /// </summary>
        void getBound(double *&bound);

        /// <summary>
        /// 设置包围盒
        /// </summary>
        void setBound(double *bound);

        /// <summary>
        /// 根据经纬度设置单个属性值
        /// </summary>
        bool setValue(GeoCoord coords, T value, int bandId);

        /// <summary>
        /// 根据code设置单个属性值
        /// </summary>
        bool setValue(DGGSElementCode code, T value, int bandId);

        /// <summary>
        /// 根据code获取单个属性值
        /// </summary>
        T getValue(DGGSElementCode code, int bandId);

        /// <summary>
        /// 根据经纬度获取单个属性值
        /// </summary>
        T getValue(GeoCoord coord, int bandId);

        DGGSFieldLayer<T>& operator=(const DGGSFieldLayer<T>& other);

        void deepCopy( DGGSFieldLayer<T> other);

        /// <summary>
        /// 分配内存
        /// </summary>
        void malBuffer();

        /// <summary>
        /// 导出文件
        /// </summary>
        /// <param name="tagFilePath">文件夹路径</param>
        /// <returns></returns>
        bool saveToFile(const char* tagFilePath);

        /// <summary>
        /// 加载文件
        /// </summary>
        /// <param name="fieldFileName">文件路径</param>
        /// <returns></returns>
        bool loadFromFile(const char* fieldFileName);
    };

    template<typename T>
    void DGGSFieldLayer<T>::setBandCount(int bandCount)
    {
        this->_bandCount = bandCount;
        this->_bands = new DGGSFieldBand<T>[this->_bandCount];
        if(this->_bound!= nullptr&&this->_bandCount!=0)
            malBuffer();
    }

    template<typename T>
    void DGGSFieldLayer<T>::malBuffer()
    {
        //用来设置GridBox
        DGGridBBox* _gridBBoxes = nullptr;
        int _gridBBoxCount = 0;

        //默认十个基菱形
        if (this->_bound == nullptr || (abs(this->_bound[1] - this->_bound[0] + 180) < 1) && (abs(this->_bound[2] - this->_bound[3] + 360) < 1))
        {
            _gridBBoxCount = baseDiamondCount;
            _gridBBoxes = new DGGridBBox[_gridBBoxCount];
            long long int maxRow = rowMaxSize(this->_level);
            for (int i = 0; i < _gridBBoxCount; i++)
            {
                _gridBBoxes[i].basePartition = i + 1;
                _gridBBoxes[i].colMax = maxRow - 1;
                _gridBBoxes[i].rowMin = 0;
                _gridBBoxes[i].colSize = maxRow;
                _gridBBoxes[i].rowSize = maxRow;
            }
            //逐个开辟空间
            for (int b = 0; b < this->_bandCount; b++)
            {
                this->_bands[b] = DGGSFieldBand<T>(b, this->_level, this->_gridType, this->_elementType, baseDiamondCount);
                for (int p = 0; p < _gridBBoxCount; p++)
                    this->_bands[b].setPartitionBoxFromIndex(_gridBBoxes[p], p);
            }
        }
        else
        {
            int* partition = nullptr;
            int partCount;
            getBasePartitions(this->_bound, partition, partCount);

            _gridBBoxCount = partCount;
            _gridBBoxes = new DGGridBBox[_gridBBoxCount];
            for (int p = 0; p < partCount; p++)
                _gridBBoxes[p].basePartition = partition[p];
            delete[]partition;

            this->getBoxFromBound(this->_bound, _gridBBoxes, partCount);

            for (int b = 0; b < this->_bandCount; b++)
            {
                this->_bands[b] = DGGSFieldBand<T>(b, this->_level, this->_gridType, this->_elementType, partCount);
                for (int p = 0; p < partCount; p++)
                    this->_bands[b].setPartitionBoxFromIndex(_gridBBoxes[p], p);
            }

        }
        delete[]_gridBBoxes;
    }

    template<typename T>
    void DGGSFieldLayer<T>::setBound(double *bound)
    {
        if(this->_bound== nullptr)
            this->_bound=new double[4];
        //设置包围盒
        if(bound== nullptr)
        {
            this->_bound[0]=90;
            this->_bound[1]=-90;
            this->_bound[2]=-180;
            this->_bound[3]=180;
        }
        else
        {
            for (int i = 0; i < 4; i++)
                this->_bound[i] = bound[i];
        }

        if(this->_bound!= nullptr&&this->_bandCount!=0)
            malBuffer();
    }

    template<typename T>
    void DGGSFieldLayer<T>::getBound(double *&bound) {
        if(bound== nullptr)
            bound=new double[4];
        for (int i = 0; i < 4; i++)
            bound[i]=this->_bound[i];
    }

    template<typename T>
    double DGGSFieldLayer<T>::calculateDiffer(int level) {
        double area = 4 * M_PI * earthRadius * earthRadius * 1000 * 1000; // 总面积
        double unitArea = area / (pow(2, 2 * level) * baseDiamondCount); // 单位面积
        double sideLength = sqrt(unitArea / (3 * sqrtThree / 2));
        double resolution = sideLength / (sqrtThree / 3); // 分辨率
        double angle = resolution / (M_PI * earthRadius * 1000 / 180); // 角度
        return angle;
    }

    template<typename T>
    void  DGGSFieldLayer<T>::getBoxFromBound(const double* bound, DGGridBBox*& gridBBoxes, int gridBoxCount)
    {
        //用于存储各个基菱形包围盒
        long long int colMax[baseDiamondCount]{};
        long long int colMin[baseDiamondCount]{};
        long long int rowMax[baseDiamondCount]{};
        long long int rowMin[baseDiamondCount]{};
        for (int i = 0; i < baseDiamondCount; i++)
        {
            colMin[i] = fColMaxSize(this->_level, this->_gridType);
            rowMin[i] = fColMaxSize(this->_level, this->_gridType);
            colMax[i] = -1;
            rowMax[i] = -1;
        }

        //计算分辨率
        double differ = this->calculateDiffer(this->_level);
        int xSize = (int)ceil((bound[2] - bound[3]) / -differ);
        int ySize = (int)ceil((bound[0] - bound[1]) / differ);

        IDGGSKernel* pKernel = CreateKernelObj(DGGSGridType::DGGS_ISEA4H);

        //获取包围盒
        for (int x = 0; x < xSize; x++)
        {
            for (int y = 0; y < ySize; y++)
            {
                double lon = bound[2] + differ * (x + 0.5);
                double lat = bound[0] - differ * (y + 0.5);
                GeoCoord coord{lon, lat };
                DGGSElementCode tempCode;
                tempCode.elementType = this->_elementType;
                tempCode.level = this->_level;
                pKernel->encode(coord, tempCode);

                if(tempCode.basePartition == 0 || tempCode.basePartition == 11)
                    continue;

                if (tempCode.row < rowMin[tempCode.basePartition - 1])
                    rowMin[tempCode.basePartition - 1] = tempCode.row;
                if (tempCode.row > rowMax[tempCode.basePartition - 1])
                    rowMax[tempCode.basePartition - 1] = tempCode.row;
                if (tempCode.col > colMax[tempCode.basePartition - 1])
                    colMax[tempCode.basePartition - 1] = tempCode.col;
                if (tempCode.col < colMin[tempCode.basePartition - 1])
                    colMin[tempCode.basePartition - 1] = tempCode.col;
            }
        }

        DestroyKernelObj(pKernel);

        //行列数
        long long int maxRow = rowMaxSize(this->_level);
        DGGridBBox tempGridBBoxes[baseDiamondCount];
        for (int i = 0; i < baseDiamondCount; i++)
        {
            tempGridBBoxes[i].basePartition = i + 1;

            //包围盒为空
            if (rowMax[i] - rowMin[i] + 1 <= 0 && colMax[i] - colMin[i] + 1 <= 0)
            {
                tempGridBBoxes[i].colMax = colMax[i];
                tempGridBBoxes[i].rowMin = rowMin[i];
                tempGridBBoxes[i].colSize = 0;
                tempGridBBoxes[i].rowSize = 0;
            }
            //列数大于行数
            else if (rowMax[i] - rowMin[i] + 1 > colMax[i] - colMin[i] + 1)
            {
                tempGridBBoxes[i].rowMin = rowMin[i];
                tempGridBBoxes[i].rowSize = rowMax[i] - rowMin[i] + 1;
                tempGridBBoxes[i].colSize = tempGridBBoxes[i].rowSize;
                if (tempGridBBoxes[i].colSize > colMax[i] + 1)
                    tempGridBBoxes[i].colMax = tempGridBBoxes[i].colSize - 1;
                else
                    tempGridBBoxes[i].colMax = colMax[i];

            }
            //列数小于行数
            else if (rowMax[i] - rowMin[i] + 1 < colMax[i] - colMin[i] + 1)
            {
                tempGridBBoxes[i].colMax = colMax[i];
                tempGridBBoxes[i].colSize = colMax[i] - colMin[i] + 1;
                tempGridBBoxes[i].rowSize = tempGridBBoxes[i].colSize;
                if (tempGridBBoxes[i].rowSize + rowMin[i] - 1 > maxRow - 1)
                    tempGridBBoxes[i].rowMin = rowMax[i] - tempGridBBoxes[i].rowSize + 1;
                else
                    tempGridBBoxes[i].rowMin = rowMin[i];
            }
            //列数等于行数
            else
            {
                tempGridBBoxes[i].colMax = colMax[i];
                tempGridBBoxes[i].rowMin = rowMin[i];
                tempGridBBoxes[i].colSize = colMax[i] - colMin[i] + 1;
                tempGridBBoxes[i].rowSize = rowMax[i] - rowMin[i] + 1;
            }

        }

        for (int i = 0; i < gridBoxCount; i++)
        {
            gridBBoxes[i] = tempGridBBoxes[gridBBoxes[i].basePartition - 1];
        }
    }

    template<typename T>
    DGGSFieldLayer<T>::DGGSFieldLayer(int bandCount, DGGSDataType dataType, DGGSElementType elementType, DGGSGridType gridType, int level, double* bound)
    {
        this->_bandCount = bandCount;
        this->_dataType = dataType;
        this->_level = level;
        this->_elementType = elementType;
        this->_gridType = gridType;
        this->setBandCount(bandCount);
        this->setBound(bound);
    }

    template<typename T>
    DGGSFieldLayer<T>::DGGSFieldLayer()
    {
        this->_bands = nullptr;
    }

    template<typename T>
    DGGSFieldLayer<T>::~DGGSFieldLayer()
    {
        if (this->_bands != nullptr)
            delete[] this->_bands;
        this->_bands= nullptr;
        if (this->_bound != nullptr)
        delete[]this->_bound;
    }

    template<typename T>
    DGGSFieldBand<T>* DGGSFieldLayer<T>::getBand(int bandId)
    {
        if (bandId >= 0 && bandId < this->_bandCount)
            return &this->_bands[bandId];
        else
            return nullptr;
    }


    template<typename T>
    T DGGSFieldLayer<T>::getValue(GeoCoord coord, int bandId)
    {
        if (bandId >= 0 && bandId < this->_bandCount)
            return this->_bands[bandId].getData(coord);
        else
            return (T)noData;
    }

    template<typename T>
    T DGGSFieldLayer<T>::getValue(DGGSElementCode code, int bandId)
    {
        if (bandId >= 0 && bandId < this->_bandCount)
        {
            auto band = this->getBand(bandId);
            return band->getData(code);
        }
        else//没有找到
            return (T)noData;
    }

    template<typename T>
    bool DGGSFieldLayer<T>::setValue(DGGSElementCode code, T value, int bandId)
    {
        if (bandId >= 0 && bandId < this->_bandCount)
        {
            auto band = this->getBand(bandId);
            return band->setData(code, value);
        }
        else//没有找到
            return false;
    }

    template<typename T>
    bool DGGSFieldLayer<T>::setValue(GeoCoord coord, T value, int bandId)
    {
        if (bandId >= 0 && bandId < this->_bandCount)
        {
            auto band = this->getBand(bandId);
            return band->setData(coord, value);
        }
        else//没有找到
            return false;
    }

    template<typename T>
    DGGSFieldLayer<T>& DGGSFieldLayer<T>::operator=(const DGGSFieldLayer<T>& other)
    {
        if (this != &other) {
            // 删除当前对象的 _bands 数组
            if (this->_bands != nullptr)
                delete[] this->_bands;
            // 复制其他成员变量
            this->_level = other._level;
            this->_dataType = other._dataType;
            this->_bandCount = other._bandCount;
            this->_gridType = other._gridType;
            this->_elementType = other._elementType;
            // 分配新的 _bands 数组并进行深度复制
            this->_bands = new DGGSFieldBand<T>[this->_bandCount];
            for (int b = 0; b < this->_bandCount; b++) {
                this->_bands[b] = other._bands[b]; // 确保 DGGSFieldBand<T> 的复制构造函数正确地复制了对象
            }
        }
        return *this;
    }

    template<typename T>
    void DGGSFieldLayer<T>::deepCopy(DGGSFieldLayer<T> other)
    {
        // 删除当前对象的 _bands 数组
        if (this->_bands != nullptr)
            delete[] this->_bands;
        // 复制其他成员变量
        this->_level = other._level;
        this->_dataType = other._dataType;
        this->_bandCount = other._bandCount;
        this->_gridType = other._gridType;
        this->_elementType = other._elementType;
        // 分配新的 _bands 数组并进行深度复制
        this->_bands = new DGGSFieldBand<T>[this->_bandCount];
        for (int b = 0; b < this->_bandCount; b++)
        {
            this->_bands[b].deepCopy(other._bands[b]);
        }
    }

#pragma region   Field的GridTIFF读写实现
        template<typename T>
        GridTransform DGGSFieldLayer<T>::getGridTransFromGridBox(DGGridBBox gridBBox)
        {
            GridTransform gridTrans{};
            gridTrans.level=this->_level;
            gridTrans.rowOrigin=gridBBox.rowMin;
            gridTrans.colOrigin=gridBBox.colMax+1-gridBBox.colSize;
            gridTrans.basePartition=gridBBox.basePartition;
            return gridTrans;
        }

        template<typename T>
        bool DGGSFieldLayer<T>::getPartitionValues(int bandId, DGGridBBox gridBBox,T*&GridTIFFValues)
        {
            auto fieldBand=this->getBand(bandId);
            DGGSElementType elementType=fieldBand->getElementType();
            int level=fieldBand->getLevel();

            //初始化数组
            int xSize=(int) gridBBox.rowSize*2;
            int ySize=(int) gridBBox.colSize*2;
            for(int i=0;i<xSize*ySize;i++)
                GridTIFFValues[i]=fieldBand->getNoDataValue();

            //获取该基菱形的数据
            long long int rowMax=gridBBox.rowSize+gridBBox.rowMin-1;
            long long int colMin=gridBBox.colMax-gridBBox.colSize+1;
            for(long long int row=gridBBox.rowMin;row<=rowMax;row++)
            {
                for(long long int col=colMin;col<=gridBBox.colMax;col++)
                {
                    DGGSElementCode code;
                    code.level=level;
                    code.basePartition=gridBBox.basePartition;
                    code.elementType=elementType;
                    code.row=row;
                    code.col=col;

                    T pixValue=fieldBand->getData(code);
                    int x,y;
                    fieldBand->code2XY(code,x,y,gridBBox);

                    GridTIFFValues[(static_cast<long long>(ySize) - 2 - y) * xSize + x] = pixValue;
                    GridTIFFValues[(static_cast<long long>(ySize) - 2 - y) * xSize + x + 1] = pixValue;
                }
            }
            return true;
        }

        template<typename T>
        bool DGGSFieldLayer<T>::saveToFile(const char *tagFilePath)
        {
            std::filesystem::path path(tagFilePath);
            std::string fileName = path.filename().string();
            std::string fieldJsonFile= std::string(tagFilePath) + "/" + fileName + ".json";

            //写入json
            std::ofstream jsonFile;
            jsonFile.open(fieldJsonFile);
            Json::StreamWriterBuilder builder;
            const std::unique_ptr<Json::StreamWriter> writer(builder.newStreamWriter());
            Json::Value root;
            root["name"] = "FieldLayer";
            root["level"] = Json::Value(this->_level);
            root["bandCount"]=Json::Value(this->_bandCount);
            root["dataType"]= enum2String(this->getDataType()).c_str();
            root["elementType"]=enum2String(this->getElementType()).c_str();
            root["gridType"]=enum2String(this->getGridType()).c_str();

            auto bound=new double[4];
            this->getBound(bound);

            //存储包围盒
            Json::Value jsonBound;
            jsonBound["maxLat"]= Json::Value(bound[0]);
            jsonBound["minLat"]= Json::Value(bound[1]);
            jsonBound["minLon"]= Json::Value(bound[2]);
            jsonBound["maxLon"]= Json::Value(bound[3]);
            root["bound"]=jsonBound;
            delete[]bound;

            //遍历十份基菱形
            for(int b=1;b<=baseDiamondCount;b++)
            {
                DGGridBBox gridBBox;
                bool isSuccess=this->getBand(0)->getGridBoxFromPartitionIndex(gridBBox,b);
                if(!isSuccess)
                    continue;

                //写入json文件
                Json::Value partParam;
                Json::Value boundBox;
                boundBox["basePartition"]  = gridBBox.basePartition;
                boundBox["rowMin"]  = gridBBox.rowMin;
                boundBox["rowSize"] = gridBBox.rowSize;
                boundBox["colSize"] = gridBBox.colSize;
                boundBox["colMax"]  = gridBBox.colMax;
                partParam["boundBox"]= boundBox;
                root["partParam"].append(partParam);
            }
            writer->write(root, &jsonFile);
            root.clear();
            jsonFile.close();

            std::filesystem::path p(fieldJsonFile);
            auto fieldFilePath=p.parent_path().string();
            //遍历十份基菱形
            for(int b=1;b<=baseDiamondCount;b++)
            {
                DGGridBBox gridBBox;
                bool isSuccess=this->getBand(0)->getGridBoxFromPartitionIndex(gridBBox,b);
                if(!isSuccess)
                    continue;
                //创建gridTiff文件
                std::string gridFileName= std::string(fieldFilePath) + "/" + std::to_string(b-1) +levels[_level]+ ".tiff";
                GridTIFF gridTiff;
                GridTransform gridTransform=this->getGridTransFromGridBox(gridBBox);
                int gridSize=(int)gridBBox.rowSize;
                gridTiff.setSize(gridSize);
                gridTiff.setDataType(this->getDataType());
                gridTiff.setBandCount(this->_bandCount);
                gridTiff.setTrans(gridTransform);
                gridTiff.setElementType(this->getElementType());
                gridTiff.setGridType(this->getGridType());
                gridTiff.setNoValue(this->getBand(0)->getNoDataValue());
                for(int bandId=0;bandId<this->_bandCount;bandId++)
                {
                    T *tagValueList=reinterpret_cast<T*>(gridTiff.getBandValue(bandId));
                    std::fill(tagValueList,tagValueList+gridSize*gridSize*4,noData);
                    getPartitionValues(bandId, gridBBox, tagValueList);
                }
                gridTiff.saveToFile(gridFileName.c_str());
            }

            return true;
        }

/*****************************************************************************************************************/
        template<typename T>
        bool DGGSFieldLayer<T>::isTiffFile(const char* fileName) {
            // 检查输入是否为空
            if (fileName == nullptr) {
                return false;
            }
            std::string file_name(fileName);
            // 查找最后一个路径分隔符
            std::string::size_type last_slash_pos = file_name.find_last_of("/\\");
            if (last_slash_pos != std::string::npos) {
                file_name.erase(0, last_slash_pos + 1);
            }

            // 检查后缀是否为".tiff"或".tif"
            if (file_name.length() > 5 && file_name.substr(file_name.length() - 5) == ".tiff"){
                return true;
            } else if (file_name.length() > 4 && file_name.substr(file_name.length() - 4) == ".tif") {
                return true;
            }
            return false;
        }

        template<typename T>
        DGGridBBox DGGSFieldLayer<T>::getGridBoxFromGridTrans(GridTransform gridTrans,int gridSize)
        {
            DGGridBBox gridBBox;
            gridBBox.basePartition=gridTrans.basePartition;
            gridBBox.colSize=gridSize;
            gridBBox.rowSize=gridSize;
            gridBBox.rowMin=gridTrans.rowOrigin;
            gridBBox.colMax=gridTrans.colOrigin+gridBBox.colSize-1;

            return gridBBox;
        }

        template<typename T>
        bool DGGSFieldLayer<T>::setBandValues(int bandId, DGGridBBox gridBBox, T *GridTIFFValues)
        {
            auto fieldBand=this->getBand(bandId);
            DGGSElementType elementType=fieldBand->getElementType();
            int level=fieldBand->getLevel();

            //初始化数组
            int xSize=(int) gridBBox.rowSize*2;
            int ySize=(int) gridBBox.colSize*2;

            //获取该基菱形的数据
            long long int rowMax=gridBBox.rowSize+gridBBox.rowMin-1;
            long long int colMin=gridBBox.colMax-gridBBox.colSize+1;
            for(long long int row=gridBBox.rowMin;row<=rowMax;row++)
            {
                for(long long int col=colMin;col<=gridBBox.colMax;col++)
                {
                    DGGSElementCode code;
                    code.level=level;
                    code.basePartition=gridBBox.basePartition;
                    code.elementType=elementType;
                    code.row=row;
                    code.col=col;

                    int x,y;
                    fieldBand->code2XY(code,x,y,gridBBox);
                    T pixValue=GridTIFFValues[(static_cast<long long>(ySize) - 2 - y) * xSize + x];
                    if(pixValue==fieldBand->getNoDataValue())
                        pixValue=(T)noData;
                    fieldBand->setData(code, pixValue);
                }
            }
            return true;
        }

        template<class T>
        void DGGSFieldLayer<T>::loadFromJson(const char* fieldJsonFile)
        {
            std::ifstream jsonFile(fieldJsonFile);
            if (!jsonFile.is_open()) {
                std::cerr << "Failed to open file." << std::endl;
                return ;
            }
            Json::Value root;
            Json::CharReaderBuilder builder;
            std::string errs;
            if (!parseFromStream(builder, jsonFile, &root, &errs)) {
                std::cerr << "Failed to parse JSON: " << errs << std::endl;
                return ;
            }
            int level=root["level"].asInt();
            int bandCount=root["bandCount"].asInt();
            auto dataType= getDataTypeFromStr(root["dataType"].asCString());
            auto elementType= getElementTypeFromStr(root["elementType"].asCString());
            auto gridType=getGridTypeFromStr(root["gridType"].asCString());
            Json::Value jsonBound=root["bound"];
            auto bound=new double[4];
            if(!jsonBound.isNull())
            {
                bound[0]=jsonBound["maxLat"].asDouble();
                bound[1]=jsonBound["minLat"].asDouble();
                bound[2]=jsonBound["minLon"].asDouble();
                bound[3]=jsonBound["maxLon"].asDouble();
            }
            this->setBandCount(bandCount);
            this->setDataType(dataType);
            this->setElementType(elementType);
            this->setGridType(gridType);
            this->setLevel(level);
            this->setBound(bound);

            delete[]bound;
            root.clear();
            jsonFile.close();

            std::filesystem::path p(fieldJsonFile);
            auto fieldFilePath=p.parent_path().string();
            //获取gridTiff数据文件目录
            std::vector<std::string>fileNames;
            for (const auto& entry : std::filesystem::directory_iterator(fieldFilePath))
                if (entry.path().extension() == ".tiff")
                    fileNames.push_back(entry.path().stem().string());

            //遍历所有菱形
            int validBaseCount=fileNames.size();
            for(int baseIndex=0;baseIndex<validBaseCount;baseIndex++)
            {
                std::string currentFileName = std::string(fieldFilePath) + "\\" + fileNames[baseIndex] + ".tiff";
                GridTIFF gridTiff;
                gridTiff.loadFromFile(currentFileName.c_str());
                //获取包围盒
                GridTransform gridTrans=gridTiff.getTrans();
                int gridSize=(int)gridTiff.getSize();
                DGGridBBox gridBBox= getGridBoxFromGridTrans(gridTrans,gridSize);
                //遍历所有波段
                int bandCount=gridTiff.getBandCount();
                for(int bandId=0;bandId<bandCount;bandId++)
                {
                    T *tagValueList=reinterpret_cast<T*>(gridTiff.getBandValue(bandId));
                    setBandValues(bandId,gridBBox,tagValueList);
                }
            }
        }

        template<class T>
        bool DGGSFieldLayer<T>::loadFromGridTiff(const char* fieldFileName)
        {
            //加载单个gridTiff数据
            GridTIFF gridTiff;
            gridTiff.loadFromFile(fieldFileName);

            //获取包围盒
            GridTransform gridTrans=gridTiff.getTrans();
            int gridSize=(int)gridTiff.getSize();
            DGGridBBox gridBBox= getGridBoxFromGridTrans(gridTrans,gridSize);

            DGGSElementType elementType=gridTiff.getElementType();
            DGGSGridType gridType=gridTiff.getGridType();
            DGGSDataType dataType=gridTiff.getDataType();

            double bound[4];
            DGGSElementCode codes[4];
            GeoCoord coord[4];
            for(int i=0;i<4;i++)
            {
                codes[i].basePartition=gridTrans.basePartition;
                codes[i].level=gridTrans.level;
                codes[i].elementType=elementType;
                codes[i].row=gridTrans.rowOrigin;
                codes[i].col=gridTrans.colOrigin;
            }
            codes[0].col=gridBBox.colMax;
            codes[1].row=gridBBox.rowMin+gridBBox.rowSize-1;
            codes[2];
            codes[3].row=gridBBox.rowMin+gridBBox.rowSize-1;
            codes[3].col=gridBBox.colMax;

            auto pKernel= CreateKernelObj(gridType);
            for(int i=0;i<4;i++)
                pKernel->decode(codes[i],coord[i]);
            bound[0]=coord[0].lat;
            bound[1]=coord[1].lat;
            bound[2]=coord[2].lon;
            bound[3]=coord[3].lon;

            this->setBandCount(gridTiff.getBandCount());
            this->setDataType(dataType);
            this->setElementType(elementType);
            this->setGridType(gridType);
            this->setLevel(gridTrans.level);
            this->setBound(bound);

            //遍历所有波段
            int bandCount=gridTiff.getBandCount();
            for(int bandId=0;bandId<bandCount;bandId++)
            {
                T *tagValueList=reinterpret_cast<T*>(gridTiff.getBandValue(bandId));
                setBandValues(bandId,gridBBox,tagValueList);
            }
            return true;
        }

        template<class T>
        bool DGGSFieldLayer<T>::loadFromFile(const char* fieldFileName)
        {
            if (!std::filesystem::exists(fieldFileName)) {
                return false;
            }
            else if(isTiffFile(fieldFileName))
                loadFromGridTiff(fieldFileName);
            else
            {
                std::string jsonFileName(fieldFileName);
                // 查找最后一个路径分隔符
                std::string::size_type last_slash_pos = jsonFileName.find_last_of("/\\");
                if (last_slash_pos != std::string::npos) {
                    jsonFileName.erase(0, last_slash_pos + 1);
                }
                // 检查后缀是否为".json"
                if (jsonFileName.length() > 5 && jsonFileName.substr(jsonFileName.length() - 5) == ".json")
                    loadFromJson(fieldFileName);
                else
                    return false;
            }
            return true;
        }
#pragma endregion

}
_NNU_DGGS_END